#pragma once
//
//
//  @ Project : Adamantium Project
//  @ File Name : GalaxyMap.cpp
//  @ Date : 12/5/2012
//  @ Author : 
//
//


#include "GalaxyMap.h"
#include <time.h>

GalaxyMap::GalaxyMap() {
	m_bDrawGalaxy = false;//want to draw SRmap quadrant as main.
	DarkSpace.isDarkSpace = true;
}

TemplateVector<SRMap*> GalaxyMap::getCurrentLRS(V2DI a_pos) {
	TemplateVector<SRMap*> surroundingQuadrants;
	//expecting a_pos passed in with 0,0 being top left and 9,9 being bottom right
	int arrayPos = (a_pos.y * 10) + a_pos.x;

	//adding in all 9 manually
	if( (a_pos.x != 0) && (a_pos.y != 0))	surroundingQuadrants.add( m_quadrants[arrayPos - 11]);
	else surroundingQuadrants.add( &DarkSpace);//adds darkspace to represent out of bounds
	if( a_pos.y != 0)	surroundingQuadrants.add( m_quadrants[arrayPos - 10]);
	else surroundingQuadrants.add( &DarkSpace);//adds darkspace to represent out of bounds
	if( (a_pos.x != 9) && (a_pos.y != 0))	surroundingQuadrants.add( m_quadrants[arrayPos - 9]);
	else surroundingQuadrants.add( &DarkSpace);//adds darkspace to represent out of bounds
	
	if( a_pos.x != 0)	surroundingQuadrants.add( m_quadrants[arrayPos - 1]);//left
	else surroundingQuadrants.add( &DarkSpace);//adds darkspace to represent out of bounds
	
	surroundingQuadrants.add( m_quadrants[arrayPos]);//center

	if( a_pos.x != 9)	surroundingQuadrants.add( m_quadrants[arrayPos + 1]);//right
	else surroundingQuadrants.add( &DarkSpace);//adds darkspace to represent out of bounds
	
	if( (a_pos.x != 0) && (a_pos.y != 9))	surroundingQuadrants.add( m_quadrants[arrayPos + 9]);
	else surroundingQuadrants.add( &DarkSpace);//adds darkspace to represent out of bounds
	if( a_pos.y != 9)	surroundingQuadrants.add( m_quadrants[arrayPos + 10]);
	else surroundingQuadrants.add( &DarkSpace);//adds darkspace to represent out of bounds
	if( (a_pos.x != 9) && (a_pos.y != 9))	surroundingQuadrants.add( m_quadrants[arrayPos + 11]);
	else surroundingQuadrants.add( &DarkSpace);//adds darkspace to represent out of bounds
	//end adding quadrants

	//since area is explored, set all to true for isExplored
	setLRSExplored(surroundingQuadrants);

	return surroundingQuadrants;
}

GalaxyMap::~GalaxyMap() {

}

void GalaxyMap::release() {
	for(int i = 0; i < GALAXY_QUADRANT_SIZE; ++i) {
		delete m_quadrants[i];
	}
	//remember to release m_quadrants to get back the memory used by the New operator
	m_quadrants.release();
}

void GalaxyMap::init(BeanieCore * a_core, V2DI * a_galaxyPosition,
		V2DI * a_QuadrantPosition) 
{
	m_core = a_core;

	m_pGalaxyPosition = a_galaxyPosition;
	m_pQuadrantPosition = a_QuadrantPosition;

	//set background texture
	backgroundUScale = 1.171875f;
	m_backgroundOffset.x = 640;//trying to set near middle of screen
	m_backgroundOffset.y = 360;
	m_mapBackground.initTexture(a_core, "sprites/starsBackground3.png", TEX_CENTER,
		m_backgroundOffset, V2DF( 1, 1), 0.0f);
	m_mapBackground.update();
	m_mapBackground.m_scl.x = backgroundUScale;
	m_mapBackground.m_scl.y = backgroundUScale;
	m_mapBackground.update();
	//set enemy texture
	m_EnemySprite.initTexture(a_core, "sprites/enemyship.png", TEX_CENTER,
		V2DF(0,0), V2DF(1,1), 0.0f);
	m_EnemySprite.update();
	m_EnemySprite.m_scl.x = 0.8f;
	m_EnemySprite.m_scl.y = 0.8f;
	m_EnemySprite.update();
	//set star texture
	m_StarSprite.initTexture(a_core, "sprites/sun.png", TEX_CENTER,
		V2DF(0,0), V2DF(1,1), 0.0f);
	m_StarSprite.update();
	m_StarSprite.m_scl.x = 0.8f;
	m_StarSprite.m_scl.y = 0.8f;
	m_StarSprite.update();

	//define grid lines by the background texture scale and offset
	m_gridlineTopLeft.x = m_backgroundOffset.x - ( (512/*size of texture*/ * backgroundUScale)/2);
	m_gridlineTopLeft.y = m_backgroundOffset.y - ( (512/*size of texture*/ * backgroundUScale)/2);
	m_gridlineTopRight.x = m_backgroundOffset.x + ( (512/*size of texture*/ * backgroundUScale)/2);
	m_gridlineTopRight.y = m_backgroundOffset.y - ( (512/*size of texture*/ * backgroundUScale)/2);
	
	m_gridlineBottomLeft.x = m_backgroundOffset.x - ( (512/*size of texture*/ * backgroundUScale)/2);
	m_gridlineBottomLeft.y = m_backgroundOffset.y + ( (512/*size of texture*/ * backgroundUScale)/2);
	m_gridlineBottomRight.x = m_backgroundOffset.x + ( (512/*size of texture*/ * backgroundUScale)/2);
	m_gridlineBottomRight.y = m_backgroundOffset.y + ( (512/*size of texture*/ * backgroundUScale)/2);
	
	//set horizontal line points and vertical line points
	for(int i = 0; i < GRIDLINES_AMMOUNT; ++i) {
		m_HGridPointLeft[i].x = m_gridlineTopLeft.x;
		m_HGridPointRight[i].x = m_gridlineTopRight.x;
		m_HGridPointLeft[i].y = m_HGridPointRight[i].y 
			= m_gridlineTopLeft.y + ( (i+1)*GRIDLINES_MARGIN);

		m_VGridPointTop[i].y = m_gridlineTopLeft.y;
		m_VGridPointBottom[i].y = m_gridlineBottomLeft.y;
		m_VGridPointTop[i].x = m_VGridPointBottom[i].x
			= m_gridlineTopLeft.x + ( (i+1)*GRIDLINES_MARGIN);
	}

	m_quadrants.allocateToSize( GALAXY_QUADRANT_SIZE);
	//create 100 quadrants, a 10x10 grid, for the galaxy ie m_quadrants
	for(int i = 0; i < GALAXY_QUADRANT_SIZE; ++i) {
		m_quadrants.add( new SRMap());
	}

	//get random number for picking quadrant first
	//then get random numbers at and between 0 and 9 to set the X and Y pos of object
	//do this for enemies first then stars second
	int numSupernovas = 5;//five percent went supernova
	srand( time(NULL));

	do{
		int a_randNum = rand() % 100;
		if( !m_quadrants[a_randNum]->superNova) {//if not supernova already, then make it supernova
			m_quadrants[a_randNum]->superNova = true;
			--numSupernovas;
		}
	}while(numSupernovas);

	int numEnemies = 300;//number of enemies to test start the galaxy
	do{
		int a_randNum = rand() % 100;
		if( m_quadrants[a_randNum]->enemyNumbers() < 9/*max number in quadrant*/) {
			int a_x = rand() % 10; int a_y = rand() % 10;
			if( !m_quadrants[a_randNum]->checkObjectAt(V2DI(a_x,a_y)) ) {
				m_quadrants[a_randNum]->addEnemyPos(V2DI(a_x,a_y));
				--numEnemies;
			}
		}
	}while(numEnemies);

	int numStars = 300;//number of stars in the galaxy
	do{
		int a_randNum = rand() % 100;
		if( m_quadrants[a_randNum]->starNumbers() < 9/*max number in quadrant*/) {
			int a_x = rand() % 10; int a_y = rand() % 10;
			if( !m_quadrants[a_randNum]->checkObjectAt(V2DI(a_x,a_y)) ) {
				m_quadrants[a_randNum]->addStarPos(V2DI(a_x,a_y));
				--numStars;
			}
		}
	}while(numStars);
}

void GalaxyMap::draw()
{
	//draw texture background for galaxymap
	m_mapBackground.draw();
	int arrayGalaxyPosition = (m_pGalaxyPosition->y * 10) + m_pGalaxyPosition->x;//assuming galaxyPosition is never higher than 9 and lowest is at 0
	//then draw grid lines

	//horizontal top to bottom
	m_core->drawLine( m_gridlineTopLeft, m_gridlineTopRight,GRIDLINES_COLOUR);
	m_core->drawLine( m_gridlineBottomLeft, m_gridlineBottomRight,GRIDLINES_COLOUR);
	//vertical lines left to right
	m_core->drawLine( m_gridlineTopLeft, m_gridlineBottomLeft,GRIDLINES_COLOUR);
	m_core->drawLine( m_gridlineTopRight, m_gridlineBottomRight,GRIDLINES_COLOUR);
	//gridlines
	for(int i = 0; i < GRIDLINES_AMMOUNT; ++i) {
		m_core->drawLine( m_HGridPointLeft[i], m_HGridPointRight[i], GRIDLINES_COLOUR);
		m_core->drawLine( m_VGridPointTop[i], m_VGridPointBottom[i], GRIDLINES_COLOUR);
	}
	//then draw enemies and stars based upon m_currentPos for array to look at
	//OR if drawgalaxy bool is true then draw numbers for explored spaces
	if(!m_bDrawGalaxy) {//if not drawing galaxy map, then draw quadrant enemies and stars and player
		if(m_quadrants[arrayGalaxyPosition]->enemyNumbers()) {//if any enemies in quadrant, draw them
			int enemyNumbers = m_quadrants[arrayGalaxyPosition]->enemyNumbers();
			TemplateVector<V2DI> enemies = m_quadrants[arrayGalaxyPosition]->getEnemyPos();
			for(int i = 0; i < enemyNumbers; ++i) {
				m_EnemySprite.m_pos.x = m_gridlineTopLeft.x + (GRIDLINES_MARGIN*0.5f) + (enemies[i].x * GRIDLINES_MARGIN); 
				m_EnemySprite.m_pos.y = m_gridlineTopLeft.y + (GRIDLINES_MARGIN*0.5f) + (enemies[i].y * GRIDLINES_MARGIN); 
				m_EnemySprite.update();
				m_EnemySprite.draw();
			}
		}
		if(m_quadrants[arrayGalaxyPosition]->starNumbers()) {//if any stars in quadrant, draw them
			int starNumbers = m_quadrants[arrayGalaxyPosition]->starNumbers();
			TemplateVector<V2DI> stars = m_quadrants[arrayGalaxyPosition]->getStarPos();
			for(int i = 0; i < starNumbers; ++i) {
				m_StarSprite.m_pos.x = m_gridlineTopLeft.x + (GRIDLINES_MARGIN*0.5f) + (stars[i].x * GRIDLINES_MARGIN);
				m_StarSprite.m_pos.y = m_gridlineTopLeft.y + (GRIDLINES_MARGIN*0.5f) + (stars[i].y * GRIDLINES_MARGIN);
				m_StarSprite.update();
				m_StarSprite.draw();
			}
		}
		//then draw player sprite when implimented

		//end drawing sprites in quadrant
	}
	else {//if drawgalaxy is true then draw numbers around explored spaces
		
		for(int i = 0; i < GALAXY_QUADRANT_SIZE; ++i){
			if(m_quadrants[i]->isExplored && !m_quadrants[i]->superNova) {//drawing text if quadrant is explored and not supernovad
				char temp[10];
				sprintf(temp, "%d%d%d", 0/*starbases*/, 
					m_quadrants[i]->enemyNumbers()/*enemies*/,
					m_quadrants[i]->starNumbers()/*stars*/);
				V2DF gridOffset = V2DF(m_gridlineTopLeft.x + (GRIDLINES_MARGIN*0.5f) + (i%10 * GRIDLINES_MARGIN),
					m_gridlineTopLeft.y + (GRIDLINES_MARGIN*0.5f) + (int(i/10) * GRIDLINES_MARGIN) );
				if( (m_pGalaxyPosition->x == i % 10) && (m_pGalaxyPosition->y == i / 10)) {
					m_core->drawText( temp, gridOffset, 0xFFFF0000);
				}
				else
					m_core->drawText( temp, gridOffset, 0xFFFFFFFF);
			}
			if(m_quadrants[i]->superNova) {//if it is supernovad, draw it.
				V2DF gridOffset = V2DF(m_gridlineTopLeft.x + (GRIDLINES_MARGIN*0.5f) + (i%10 * GRIDLINES_MARGIN),
					m_gridlineTopLeft.y + (GRIDLINES_MARGIN*0.5f) + (int(i/10) * GRIDLINES_MARGIN) );
				m_pSupernovae->m_pos = gridOffset;
				m_pSupernovae->update();
				m_pSupernovae->draw();
			}
		}
	}

}

void GalaxyMap::setLRSExplored(TemplateVector<SRMap*> &a_quadrants)
{
	for(int i = 0; i < a_quadrants.size(); ++i) {
		a_quadrants[i]->isExplored = true;
	}
}

void GalaxyMap::GrabBoundingBox(Clickable &a_box)
{
	a_box.TOP = m_gridlineTopLeft.y;
	a_box.LEFT = m_gridlineTopLeft.x;
	a_box.DOWN = m_gridlineBottomRight.y;
	a_box.RIGHT = m_gridlineBottomRight.x;
}

/** used within a for loop for filling quadrant boxes. a_arrayNum is i within for loop*/
void GalaxyMap::GrabQuadrantBoxes(Clickable &a_boxes, int a_arrayNum)
{
	//relies on gridlinetopleft being set properly
	a_boxes.TOP = m_gridlineTopLeft.y + (GRIDLINES_MARGIN * (a_arrayNum/10));
	a_boxes.LEFT = m_gridlineTopLeft.x + (GRIDLINES_MARGIN *(a_arrayNum%10));
	a_boxes.DOWN = m_gridlineTopLeft.y + (GRIDLINES_MARGIN * (a_arrayNum/10)) + GRIDLINES_MARGIN;
	a_boxes.RIGHT = m_gridlineTopLeft.x + (GRIDLINES_MARGIN * (a_arrayNum%10)) + GRIDLINES_MARGIN;
}